﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using Passwords.Controls;
using Silvermoon.Windows.Styles;
using Passwords.Utils;
using Passwords.Biz;
using System.Drawing;
using System.Diagnostics;
using Silvermoon.Images;
using Silvermoon.Shapes;
using Silvermoon.OpenGL;
using Silvermoon.Windows;
using Silvermoon.Controls.Forms;

namespace Passwords.Pages
{

    public class EditCategoryPage : Page
    {
        #region fields

        class CheckedLabel
        {
            public bool IsChecked;
            public PasswordLabel Label;
        }

        private Toolbar toolbar;
        private Category category;
        private static readonly string az = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        private ListView azListView, idxListView;
        private ListViewController<PickerItem, CheckedLabel> azController, idxController;
        private TabControl tabs;
        private List<CheckedLabel> checkedLabels;
        private TextBox textBox;

        #endregion
        #region ctor

        public EditCategoryPage()
            : base()
        {
            InitializePage();
        }

        #endregion
        #region props

        public Category Category
        {
            get { return category; }
            set
            {
                if (category != value)
                {
                    category = value;
                    OnCategoryChanged();
                }
            }
        }

        public bool IsSaveEnabled
        {
            get { return toolbar.Buttons[0].Enabled; }
            set
            {
                if (IsSaveEnabled != value)
                {
                    toolbar.Buttons[0].Enabled = value;
                }
            }
        }

        public bool IsDeleteEnabled
        {
            get { return toolbar.Buttons[1].Enabled; }
            set
            {
                if (IsDeleteEnabled != value)
                {
                    toolbar.Buttons[1].Enabled = value;
                }
            }
        }



        #endregion
        #region methods

        private void OnCategoryChanged()
        {
            if (category != null)
            {
                checkedLabels = (from l in category.Context.Labels orderby l.Name select new CheckedLabel { Label = l, IsChecked = category.ContainsLabel(l) }).ToList();
                textBox.Text = category.Name;
                IsSaveEnabled = !string.IsNullOrEmpty(category.Name);
                IsDeleteEnabled = !category.IsNew;
            }
            else
            {
                checkedLabels = null;
            }
            azController.DataSource = checkedLabels;
            idxController.DataSource = checkedLabels.OrderBy(c => c.Label.DisplayIndex);
        }


        protected virtual void InitializePage()
        {
            Title = "EDIT CATEGORY";
            Styles = StylePool.Metro;
            Style = StylePool.EditWindow;

            Styles.SetClass<PickerItem>(StylePool.DarkSelectionItem);

            textBox = new TextBox { Margin = new Margin(10, 0, 10, null), Height = 64 };
            textBox.TextChanged += new EventHandler(textBox_TextChanged);
            textBox.Watermark = new StringShape { Text = "Enter category name", Opacity = 160, Color = PhoneColors.Dark };
            tabs = new TabControl { Margin = new Margin(0, 64, 0, 0), TabSpace = 10 };
            tabs.Styles.SetClass<Label>(StylePool.TitleLabel);
            Margin m = new Margin(20, 0, 20, 0);
            azListView = new ListView { Margin = m, StyleName = "ListView", Multiselect = true };
            idxListView = new ListView { Margin = m, StyleName = "ListView", Multiselect = true };

            azController = GenerateController(azListView);
            idxController = GenerateController(idxListView);
            tabs.SetPages(new TabPage(
                new Label("indexed "), idxListView),
                new TabPage(new Label("alphabetic "), azListView)
                //,new TabPage(new Label("selection "), null)
                );
            Controls.Add(tabs, textBox);

            toolbar = new Toolbar();
            toolbar.Styles.SetClass<MenuItem>(new TextItemStyle { Font = FontCache.MediumRegularFont, Padding = new Margin(20, 0, 20, 0) });
            Toolbar = toolbar;
            toolbar.AddButton(SysImages.Ok).Tap += new EventHandler<TapEventArgs>(OnOk);
//            toolbar.AddButton(SysImages.Add).Enabled = false;
            toolbar.AddButton(SysImages.RecycleBin).Tap += new EventHandler<TapEventArgs>(OnDeleteCategory);
            toolbar.AddButton(SysImages.Cancel, Page.BackCommand);
            toolbar.AddMenuItem("Uncheck all labels").Tap += new EventHandler<TapEventArgs>(EditCategoryPage_Tap);
            toolbar.AddMenuItem("Create new label").Enabled = false;

            SetControllerIndex();

        }

        void textBox_TextChanged(object sender, EventArgs e)
        {
            IsSaveEnabled = !string.IsNullOrEmpty(textBox.Text);
        }

        void EditCategoryPage_Tap(object sender, TapEventArgs e)
        {
            foreach (var cl in checkedLabels)
            {
                cl.IsChecked = false;
            }
            azController.BindItems();
            idxController.BindItems();
        }

        protected virtual void OnDeleteCategory(object sender, TapEventArgs e)
        {
            MessageDialog.Show("Delete Category?", category.Name + " will be deleted from your passwords.", "Delete", "Cancel",
                () =>
                {
                    try
                    {
                        category.Delete();
                        GoBack();
                    }
                    catch (Exception)
                    {
                        NotifyErrorOnDelete();
                    }
                }, null);
        }

        protected override void OnShown()
        {
            base.OnShown();
            if (category != null && string.IsNullOrEmpty(category.Name))
            {
                textBox.Focus();
                textBox.SelectAll();
                IsKeyboardVisible = true;
            }
        }

        private void NotifyErrorOnDelete()
        {
            MessageDialog.Show("ERROR", "Could not delete category " + category.Name + ".");
        }

        protected virtual void OnOk(object sender, TapEventArgs e)
        {
            if (category != null)
            {
                try
                {
                    category.Labels = (from cl in checkedLabels where cl.IsChecked orderby cl.Label.DisplayIndex select cl.Label).ToArray();
                    category.Name = textBox.Text;
                    category.Save();
                    GoBack();
                }
                catch (Exception)
                {
                    NotifyErrorOnSave();
                }
            }
        }

        private void NotifyErrorOnSave()
        {
            MessageDialog.Show("ERROR", "Could not save category " + category.Name + ".");
        }

        private ListViewController<PickerItem, CheckedLabel> GenerateController(ListView listView)
        {
            var controller = new ListViewController<PickerItem, CheckedLabel>(listView) { ItemHeight = 80 };
            controller.UpdateItem += new EventHandler<ItemControlGeneratorEventArgs<PickerItem>>(controller_UpdateItem);
            controller.InitializeItem += new EventHandler<ItemControlGeneratorEventArgs<PickerItem>>(controller_InitializeItem);
            controller.GetDescriptorFromValue += new EventHandler<GroupDescriptorEventArgs<CheckedLabel>>(controller_GetDescriptorFromValue);
            //controller.GroupButtonSize = new Size(64, 64);
            controller.ItemStyle = new TextItemStyle { Font = FontCache.BigRegularFont };
            return controller;
        }

        private void SetControllerIndex()
        {
            foreach (char c in az)
            {
                azController.AddIndex(c.ToString());
            }
        }

        void controller_GetDescriptorFromValue(object sender, GroupDescriptorEventArgs<CheckedLabel> e)
        {
            string s = e.Value.Label.Name;
            char c = char.ToUpper(s.Length > 0 ? s[0] : '#');
            int index = Math.Max(0, az.IndexOf(c));
            e.Descriptor = e.GroupDescriptors[index];
        }

        void controller_InitializeItem(object sender, ItemControlGeneratorEventArgs<PickerItem> e)
        {
            var item = e.Item;
            item.SelectionChanged += new EventHandler(Item_SelectionChanged);
        }

        void Item_SelectionChanged(object sender, EventArgs e)
        {
            PickerItem item = sender as PickerItem;
            if (!item.IsInitialized || item.Host == null) return;
            CheckedLabel cl = item.DataValue as CheckedLabel;
            cl.IsChecked = item.IsSelected;
            if (tabs.SelectedPage.Container == idxListView)
            {
                azController.BindValue(cl);
            }
            else
            {
                idxController.BindValue(cl);
            }
        }


        void controller_UpdateItem(object sender, ItemControlGeneratorEventArgs<PickerItem> e)
        {
            CheckedLabel label = e.Value as CheckedLabel;
            e.Item.IsSelected = label.IsChecked;
            e.Item.Title = label.Label.Name;
        }

        #endregion
    }
}
